package io.github.wppli.infrastructure.persistent.repository;

import com.alibaba.fastjson2.JSON;
import io.github.wppli.domain.posts.event.CalculatePostsTfIdfEvent;
import io.github.wppli.domain.posts.model.aggregate.PublishPostsAggregate;
import io.github.wppli.domain.posts.model.entity.CollectPostsEntity;
import io.github.wppli.domain.posts.model.entity.PostEntity;
import io.github.wppli.domain.posts.model.entity.PostsTfIdfTaskEntity;
import io.github.wppli.domain.posts.model.entity.PublishPostsEntity;
import io.github.wppli.domain.posts.repository.IPostsRepository;
import io.github.wppli.domain.recommond.model.entity.PostsContentEntity;
import io.github.wppli.infrastructure.event.EventPublisher;
import io.github.wppli.infrastructure.persistent.dao.ILikesDao;
import io.github.wppli.infrastructure.persistent.dao.IPostsDao;
import io.github.wppli.infrastructure.persistent.dao.ITaskDao;
import io.github.wppli.infrastructure.persistent.dao.IUserDao;
import io.github.wppli.infrastructure.persistent.po.Likes;
import io.github.wppli.infrastructure.persistent.po.Posts;
import io.github.wppli.infrastructure.persistent.po.Task;
import io.github.wppli.infrastructure.persistent.po.User;
import io.github.wppli.types.event.BaseEvent;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.stream.Collectors;

/**
 * @author li--jiaqiang 2025−03−11
 */
@Slf4j
@Repository
@AllArgsConstructor
public class PostsRepository implements IPostsRepository {

    private final IPostsDao postsDao;
    private final IUserDao userDao;
    private final ILikesDao likesDao;
    private final ITaskDao taskDao;
    private final ThreadPoolExecutor executor;
    private final EventPublisher eventPublisher;

    @Override
    @Transactional
    public void publishPosts(PublishPostsAggregate publishPostsAggregate) {
        PublishPostsEntity publishPostsEntity = publishPostsAggregate.getPublishPostsEntity();
        // 1. 查询用户信息
        User user = userDao.queryUserInfoById(publishPostsEntity.getAuthorId().toString());
        // 2. 参数转换
        Posts posts = Posts.builder()
                .id(publishPostsEntity.getId())
                .authorId(publishPostsEntity.getAuthorId())
                .authorName(user.getUsername())
                .authorAvatar(user.getAvatarUrl())
                .title(publishPostsEntity.getTitle())
                .content(publishPostsEntity.getContent())
                .images(publishPostsEntity.joinImagesWithComma())
                .isPublic(publishPostsEntity.getIsPublic())
                .status(publishPostsEntity.getPostsStatus().getValue())
                .createdAt(LocalDateTime.now())
                .updatedAt(LocalDateTime.now())
                .build();
        // 3. 插入
        postsDao.insert(posts);

        // 发布事件
        executor.execute(() -> {
            PostsTfIdfTaskEntity taskEntity = publishPostsAggregate.getTaskEntity();
            BaseEvent.EventMessage<CalculatePostsTfIdfEvent.CalculatePostsTfIdfMessage> message = taskEntity.getMessage();
            CalculatePostsTfIdfEvent.CalculatePostsTfIdfMessage data = message.getData();
            Task task = Task.builder()
                    .topic(taskEntity.getTopic())
                    .messageId(taskEntity.getMessageId())
                    .message(JSON.toJSONString(message))
                    .userId(taskEntity.getUserId())
                    .state(taskEntity.getState().getCode())
                    .build();
            try {
                // 插入 task 任务
                taskDao.insertOne(task);
                // 发送消息【在事务外执行，如果失败还有任务补偿】
                eventPublisher.publish(task.getTopic(), task.getMessage());
                // 更新数据库记录，task 任务表
                taskDao.updateTaskSendMessageCompleted(task);
                log.info("帖子TF-IDF任务，发送MQ消息成功 userId: {} postsId:{} topic: {}", task.getUserId(), data.getContentId(), task.getTopic());
            } catch (Exception e) {
                log.info("帖子TF-IDF任务，发送MQ消息失败 userId: {} postsId:{} topic: {}", task.getUserId(), data.getContentId(), task.getTopic());
                taskDao.updateTaskSendMessageFail(task);
            }
        });
    }

    @Override
    public List<PostEntity> listPosts(Long authorId) {
        List<Posts> postsList = postsDao.queryPostsList(authorId);
        if (postsList.isEmpty()) {
            return Collections.emptyList();
        }
        List<PostEntity> postEntities = new LinkedList<>();
        for (Posts posts : postsList) {
            PostEntity postEntity = PostEntity.builder()
                        .id(posts.getId())
                        .authorId(posts.getAuthorId())
                        .authorName(posts.getAuthorName())
                        .authorAvatar(posts.getAuthorAvatar())
                        .title(posts.getTitle())
                        .content(posts.getContent())
                        .images(posts.getImages())
                        .likesCount(posts.getLikesCount())
                        .collectCount(posts.getCollectCount())
                        .commentsCount(posts.getCommentsCount())
                        .sharesCount(posts.getSharesCount())
                        .viewsCount(posts.getViewsCount())
                        .isSticky(posts.getIsSticky())
                        .build();
            postEntities.add(postEntity);
        }
        return postEntities;
    }

    @Override
    public PostEntity getPosts(Long postId) {
        Posts posts = postsDao.queryPostsById(postId);
        if (posts == null) {
            return null;
        }
        return PostEntity.builder()
                .id(posts.getId())
                .authorId(posts.getAuthorId())
                .authorName(posts.getAuthorName())
                .authorAvatar(posts.getAuthorAvatar())
                .title(posts.getTitle())
                .content(posts.getContent())
                .images(posts.getImages())
                .likesCount(posts.getLikesCount())
                .collectCount(posts.getCollectCount())
                .commentsCount(posts.getCommentsCount())
                .sharesCount(posts.getSharesCount())
                .viewsCount(posts.getViewsCount())
                .isSticky(posts.getIsSticky())
                .build();
    }

    @Override
    public int deletePosts(Long postId, Long authorId) {
        return postsDao.deletePosts(postId, authorId);
    }

    @Override
    public void likePosts(Long postId, int adjustCount) {
        postsDao.likePosts(postId, adjustCount);
    }

    /**
     * 插入一条点赞关系
     */
    public void insertLike(Long postId, Long userId) {
        likesDao.insert(new Likes(userId, postId, 1, LocalDateTime.now()));
    }
    /**
     * 查询点赞信息
     */
    public boolean queryLikeExist(Long postId, Long userId) {
        return likesDao.queryLikePosts(postId, userId) != null;
    }
    public void updateLikeStatus(Long postId, Long userId, int status) {
        likesDao.updateLikeStatus(postId, userId, status);
    }

    @Transactional
    public void updateOrInsertLike(Long postId, Long userId, int status) {
        if (queryLikeExist(postId, userId)) {
            updateLikeStatus(postId, userId, status);
        } else {
            insertLike(postId, userId);
        }
    }

    @Override
    public void updateCollectPostsCount(CollectPostsEntity collectPostsEntity) {
        postsDao.updateCollectPostsCount(collectPostsEntity.getPostsId(), collectPostsEntity.getUserId(), collectPostsEntity.getAdjustCount());
    }

    @Override
    public List<PostsContentEntity> queryBatchIds(List<Long> postsContentIds) {
        List<Posts> postsList = postsDao.selectBatchIds(postsContentIds);
        return getPostsContentEntities(postsList);
    }

    @Override
    public List<PostsContentEntity> findAll() {
        List<Posts> postsList = postsDao.findAll();
        return getPostsContentEntities(postsList);
    }

    @NotNull
    private List<PostsContentEntity> getPostsContentEntities(List<Posts> postsList) {
        if (postsList == null || postsList.isEmpty()) {
            return Collections.emptyList();
        }
        return postsList.stream()
                .map(posts -> PostsContentEntity.builder()
                        .id(posts.getId())
                        .authorId(posts.getAuthorId())
                        .authorName(posts.getAuthorName())
                        .authorAvatar(posts.getAuthorAvatar())
                        .title(posts.getTitle())
                        .text(posts.getContent())
                        .images(posts.getImages())
                        .likesCount(posts.getLikesCount())
                        .collectCount(posts.getCollectCount())
                        .commentsCount(posts.getCommentsCount())
                        .sharesCount(posts.getSharesCount())
                        .viewsCount(posts.getViewsCount())
                        .build())
                .collect(Collectors.toList());
    }


}